<template>
  <div>
    <div class="flex justify-between items-center mb-6">
      <h1 class="text-2xl font-bold text-gray-900">{{ isEdit ? '编辑文章' : '创建文章' }}</h1>
      <div class="flex space-x-2">
        <!-- 查看文章按钮（仅在编辑模式下显示） -->
        <a
          v-if="isEdit"
          :href="`/#/news/${article.newsId}`"
          target="_blank"
          class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[#C32A31]"
        >
          <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
          </svg>
          查看文章
        </a>
        <button @click="goBack" class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[#C32A31]">
          返回
        </button>
        <button @click="saveArticle" :disabled="saving" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-[#C32A31] hover:bg-[#991E29] focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[#C32A31]">
          {{ saving ? '保存中...' : '保存文章' }}
        </button>
      </div>
    </div>

    <!-- 表单 -->
    <div class="bg-white shadow overflow-hidden sm:rounded-lg p-6">
      <div class="grid grid-cols-1 gap-6">
        <!-- 标题 -->
        <div>
          <label for="title" class="block text-sm font-medium text-gray-700">标题</label>
          <input type="text" id="title" v-model="article.title" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-[#C32A31] focus:border-[#C32A31] sm:text-sm" placeholder="请输入文章标题" />
        </div>

        <!-- 文章ID (仅在创建模式下显示) -->
        <div v-if="!isEdit">
          <label for="newsId" class="block text-sm font-medium text-gray-700">文章ID (可选)</label>
          <input
            type="number"
            id="newsId"
            v-model="article.newsId"
            class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-[#C32A31] focus:border-[#C32A31] sm:text-sm"
            placeholder="留空将自动生成6位数字ID"
          />
          <p class="mt-1 text-xs text-gray-500">如果需要指定特定ID，请在此输入，否则系统将自动生成</p>
        </div>

        <!-- 分类 -->
        <div>
          <label for="category" class="block text-sm font-medium text-gray-700">分类</label>
          <select id="category" v-model="article.category" class="mt-1 block w-full bg-white border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-[#C32A31] focus:border-[#C32A31] sm:text-sm">
            <option value="">请选择分类</option>
            <option value="学校新闻">学校新闻</option>
            <option value="通知公告">通知公告</option>
            <option value="学术活动">学术活动</option>
            <option value="招生就业">招生就业</option>
            <option value="校园生活">校园生活</option>
          </select>
        </div>

        <!-- 学院/教务处 -->
        <div>
          <label for="section" class="block text-sm font-medium text-gray-700">学院/教务处</label>
          <select id="section" v-model="article.section" class="mt-1 block w-full bg-white border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-[#C32A31] focus:border-[#C32A31] sm:text-sm">
            <option value="">请选择学院/教务处</option>
            <option v-for="option in sectionOptions" :key="option.value" :value="option.value">{{ option.label }}</option>
          </select>
        </div>

        <!-- 导读/总结 -->
        <div>
          <label for="contentText" class="block text-sm font-medium text-gray-700">导读/总结</label>
          <textarea
            id="contentText"
            v-model="article.contentText"
            rows="3"
            class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-[#C32A31] focus:border-[#C32A31] sm:text-sm"
            placeholder="请输入文章导读或总结（可选）"
          ></textarea>
        </div>

        <!-- 原文链接 -->
        <div>
          <label for="url" class="block text-sm font-medium text-gray-700">原文链接</label>
          <input
            type="url"
            id="url"
            v-model="article.url"
            class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-[#C32A31] focus:border-[#C32A31] sm:text-sm"
            placeholder="请输入原文链接（可选）"
          />
        </div>

        <!-- 发布时间 -->
        <div>
          <label for="pubTime" class="block text-sm font-medium text-gray-700">发布时间</label>
          <input
            type="datetime-local"
            id="pubTime"
            v-model="article.pubTime"
            class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-[#C32A31] focus:border-[#C32A31] sm:text-sm"
          />
          <p class="mt-1 text-xs text-gray-500">如不填写，将使用当前时间</p>
        </div>

        <!-- 富文本编辑器 - 使用官方组件 -->
        <div>
          <label class="block text-sm font-medium text-gray-700 mb-2">内容</label>
          <div style="border: 1px solid #ccc; border-radius: 0.375rem; overflow: hidden;">
            <Toolbar
              style="border-bottom: 1px solid #ccc"
              :editor="editorRef"
              :defaultConfig="toolbarConfig"
              :mode="mode"
            />
            <Editor
              style="height: 500px; overflow-y: hidden;"
              v-model="article.contentHtml"
              :defaultConfig="editorConfig"
              :mode="mode"
              @onCreated="handleCreated"
              @onChange="handleChange"
              @onBlur="() => console.log('编辑器失去焦点')"
              @onFocus="() => console.log('编辑器获得焦点',article.contentHtml)"
            />
          </div>
        </div>

        <!-- 文章信息 -->
        <div v-if="isEdit" class="text-sm text-gray-500">
          <p>文章ID: {{ article.newsId }}</p>
          <p v-if="article.crawlTime">最后更新时间: {{ formatDateTime(article.crawlTime) }}</p>
        </div>
      </div>
    </div>

    <!-- 错误提示 -->
    <div v-if="error" class="mt-4 bg-red-50 border-l-4 border-red-400 p-4">
      <div class="flex">
        <div class="flex-shrink-0">
          <svg class="h-5 w-5 text-red-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
            <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />
          </svg>
        </div>
        <div class="ml-3">
          <p class="text-sm text-red-700">{{ error }}</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import '@wangeditor/editor/dist/css/style.css' // 引入 css

import { onBeforeUnmount, ref, reactive, shallowRef, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { articleApi } from '../../utils/api'

export default {
  components: { Editor, Toolbar },
  setup() {
    const router = useRouter()
    const route = useRoute()

    // 编辑器实例，必须用 shallowRef
    const editorRef = shallowRef()

    // 文章数据
    const article = reactive({
      newsId: null,
      title: '',
      category: '',
      contentHtml: '<p></p>',
      contentText: '',
      url: '',
      pubTime: '',
      crawlTime: '',
      section: ''
    })

    // 状态
    const isEdit = ref(false)
    const articleId = ref(null)
    const loading = ref(false)
    const saving = ref(false)
    const error = ref(null)
    const mode = ref('default')
    const sectionOptions = ref([])

    // 格式化日期时间
    const formatDateTime = (dateTimeStr) => {
      if (!dateTimeStr) return '';

      try {
        const date = new Date(dateTimeStr);
        return date.toLocaleString();
      } catch (err) {
        console.error('日期格式化错误:', err);
        return dateTimeStr;
      }
    };

    // 工具栏配置
    const toolbarConfig = {
      // 不需要额外添加uploadImage，编辑器默认已包含
    }

    // 编辑器配置
    const editorConfig = {
      placeholder: '请输入文章内容...',
      MENU_CONF: {
        uploadImage: {
          // 上传图片的配置
          server: '/api/admin/upload/image',
          fieldName: 'file',
          headers: {
            'satoken': localStorage.getItem('admin_token')
          },
          maxFileSize: 5 * 1024 * 1024, // 5MB
          allowedFileTypes: ['image/*'], // 只允许图片文件

          // 自定义插入图片 - 处理后端返回的wangEditor标准格式
          customInsert(res, insertFn) {
            console.log('图片上传响应:', res)

            // 后端现在返回wangEditor标准格式 {errno: 0, data: {...}}
            if (res.errno === 0 && res.data && res.data.url) {
              // 插入图片，使用返回的URL
              insertFn(res.data.url, res.data.alt || '', res.data.href || '')
              console.log('图片插入成功:', res.data.url)
            } else {
              console.error('图片上传失败:', res)
              // 显示错误提示
              alert('图片上传失败: ' + (res.message || '未知错误'))
            }
          },

          // 上传前的验证函数
          onBeforeUpload(file) {
            console.log('准备上传文件:', file)

            // 基本验证
            if (!file) {
              alert('请选择要上传的文件')
              return false
            }

            // 获取文件信息 - wangEditor/Uppy.js的文件对象结构
            let fileName, fileSize, fileType, actualFile

            // 检查是否是Uppy.js的文件对象集合
            if (typeof file === 'object' && !file.name && !file.size && !file.type) {
              // 这是一个包含文件ID作为键的对象，获取第一个文件
              const fileKeys = Object.keys(file)
              if (fileKeys.length > 0) {
                actualFile = file[fileKeys[0]]
                fileName = actualFile.name || actualFile.data?.name || '未知文件'
                fileSize = actualFile.size || actualFile.data?.size || 0
                fileType = actualFile.type || actualFile.data?.type || ''
              } else {
                fileName = '未知文件'
                fileSize = 0
                fileType = ''
              }
            } else if (file.data) {
              // Uppy.js单个文件对象，实际文件在data属性中
              actualFile = file
              fileName = file.data.name || file.name || '未知文件'
              fileSize = file.data.size || file.size || 0
              fileType = file.data.type || file.type || ''
            } else {
              // 标准File对象
              actualFile = file
              fileName = file.name || '未知文件'
              fileSize = file.size || 0
              fileType = file.type || ''
            }

            console.log('文件信息:', { fileName, fileSize, fileType })

            // 验证文件类型
            const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp', 'image/bmp']
            if (!fileType || !allowedTypes.includes(fileType.toLowerCase())) {
              alert('只支持图片文件格式：JPEG, PNG, GIF, WebP, BMP')
              return false
            }

            // 验证文件大小
            if (fileSize > 5 * 1024 * 1024) {
              alert('图片文件大小不能超过5MB')
              return false
            }

            return file // 返回原始文件对象，让Uppy.js正确追踪状态
          },

          // 上传进度回调
          onProgress(progress) {
            console.log('上传进度:', progress + '%')
          },

          // 单个文件上传成功
          onSuccess(file, res) {
            // 获取文件名的通用函数
            const getFileName = (fileObj) => {
              if (typeof fileObj === 'object' && !fileObj.name && !fileObj.size) {
                const keys = Object.keys(fileObj)
                if (keys.length > 0) {
                  const actualFile = fileObj[keys[0]]
                  return actualFile.name || actualFile.data?.name || '未知文件'
                }
              }
              return fileObj.data?.name || fileObj.name || '未知文件'
            }

            const fileName = getFileName(file)
            console.log('上传成功:', fileName, res)
          },

          // 单个文件上传失败
          onFailed(file, res) {
            // 获取文件名的通用函数
            const getFileName = (fileObj) => {
              if (typeof fileObj === 'object' && !fileObj.name && !fileObj.size) {
                const keys = Object.keys(fileObj)
                if (keys.length > 0) {
                  const actualFile = fileObj[keys[0]]
                  return actualFile.name || actualFile.data?.name || '未知文件'
                }
              }
              return fileObj.data?.name || fileObj.name || '未知文件'
            }

            const fileName = getFileName(file)
            console.log('上传失败:', fileName, res)
            alert(`${fileName} 上传失败`)
          },

          // 上传错误或超时
          onError(file, err, res) {
            // 获取文件名的通用函数
            const getFileName = (fileObj) => {
              if (typeof fileObj === 'object' && !fileObj.name && !fileObj.size) {
                const keys = Object.keys(fileObj)
                if (keys.length > 0) {
                  const actualFile = fileObj[keys[0]]
                  return actualFile.name || actualFile.data?.name || '未知文件'
                }
              }
              return fileObj.data?.name || fileObj.name || '未知文件'
            }

            const fileName = getFileName(file)
            console.error('上传错误:', fileName, err, res)

            let errorMessage = `${fileName} 上传失败`
            if (res && res.message) {
              errorMessage = res.message
            } else if (err && err.message) {
              errorMessage = err.message
            }

            alert(errorMessage)
          }
        }
      }
    }

    // 编辑器创建完成时的回调
    const handleCreated = (editor) => {
      editorRef.value = editor // 记录 editor 实例，重要！
      console.log('编辑器创建完成')

      // 处理第二道工序：确保编辑器能正确识别HTML格式
      if (article.contentHtml && article.contentHtml !== '<p></p>') {
        console.log('编辑器创建完成，设置HTML内容')
        // 使用setTimeout确保编辑器完全初始化
        setTimeout(() => {
          try {
            // 使用editor.setHtml方法设置内容，而不是依赖v-model
            editor.setHtml(article.contentHtml)
            console.log('成功设置编辑器HTML内容')
          } catch (err) {
            console.error('设置编辑器内容失败:', err)
          }
        }, 100)
      }
    }

    // 编辑器内容变化时的回调
    const handleChange = () => {
      // 如果没有设置导读/总结，可以从HTML内容中提取纯文本作为默认值
      if (!article.contentText.trim()) {
        try {
          // 正确的方式：通过editorRef.value获取编辑器实例
          const editorInstance = editorRef.value
          if (editorInstance) {
            // 获取纯文本内容
            const textContent = editorInstance.getText()
            // 截取前100个字符作为导读
            if (textContent.length > 0) {
              article.contentText = textContent.substring(0, 100) + (textContent.length > 100 ? '...' : '')
            }
          }
        } catch (err) {
          console.error('提取文本内容失败:', err)
        }
      }
    }

    // 获取文章详情
    const fetchArticle = async (id) => {
      loading.value = true
      error.value = null

      try {
        const result = await articleApi.getAdminArticleDetail(id)

        if (result.code === 200) {
          const articleData = result.data

          // 设置所有文章字段
          article.newsId = articleData.news_id
          article.title = articleData.title || ''
          article.category = articleData.category || ''
          article.contentText = articleData.content_text || ''
          article.url = articleData.url || ''
          article.section = articleData.section || ''

          // 处理日期时间
          if (articleData.pub_time) {
            // 将后端返回的日期时间格式转换为input datetime-local接受的格式
            try {
              const pubDate = new Date(articleData.pub_time)
              article.pubTime = pubDate.toISOString().slice(0, 16) // 格式化为 YYYY-MM-DDTHH:MM
            } catch (e) {
              console.error('发布时间格式化失败:', e)
              article.pubTime = ''
            }
          } else {
            article.pubTime = ''
          }

          // 保存最后更新时间
          article.crawlTime = articleData.crawl_time || ''

          // 保存HTML内容，进行智能处理
          let htmlContent = articleData.content_html || '<p></p>'
          console.log('原始HTML内容长度:', htmlContent.length)

          // 智能处理HTML内容的函数
          const processHtmlContent = (html) => {
            // 如果内容为空，返回默认段落
            if (!html || html.trim() === '') {
              return '<p></p>'
            }

            let processedHtml = html

            // 1. 处理第一道工序：移除外层<div id="content_article">包裹
            if (processedHtml.trim().startsWith('<div id="content_article">') && processedHtml.trim().endsWith('</div>')) {
              console.log('检测到整个HTML内容被<div id="content_article">包裹，进行处理')

              const startTag = '<div id="content_article">'
              const endTag = '</div>'

              const startPos = processedHtml.indexOf(startTag) + startTag.length
              const endPos = processedHtml.lastIndexOf(endTag)

              if (startPos > 0 && endPos > startPos) {
                processedHtml = processedHtml.substring(startPos, endPos).trim()
                console.log('成功提取出<div id="content_article">中的内容')
              }
            }

            // 2. 处理第二道工序：修复特定的HTML结构问题

            // 2.1 修复图片div，确保图片能正确显示
            // 将 <div style="text-align:center;"><img...></img></div> 转换为 <p style="text-align:center;"><img...></p>
            processedHtml = processedHtml.replace(
              /<div\s+style="text-align:(center|left|right);">\s*<img\s+([^>]*)>\s*<\/img>\s*<\/div>/gi,
              (match, align, imgAttrs) => {
                console.log('修复图片div:', match.substring(0, 50) + '...')
                return `<p style="text-align:${align};"><img ${imgAttrs}></p>`
              }
            )

            // 2.2 修复自闭合标签，wangEditor对某些自闭合标签处理不好
            // 将 <img...></img> 转换为 <img...>
            processedHtml = processedHtml.replace(
              /<img\s+([^>]*)>\s*<\/img>/gi,
              (_, imgAttrs) => {
                console.log('修复自闭合img标签')
                return `<img ${imgAttrs}>`
              }
            )

            // 2.3 修复空的或只包含换行的div
            // 将 <div><br></br></div> 转换为 <p><br></p>
            processedHtml = processedHtml.replace(
              /<div>\s*<br>\s*<\/br>\s*<\/div>/gi,
              () => {
                console.log('修复空div+br标签')
                return '<p><br></p>'
              }
            )

            // 2.4 修复空的div标签
            // 将 <div></div> 转换为 <p></p>
            processedHtml = processedHtml.replace(
              /<div>\s*<\/div>/gi,
              () => {
                console.log('修复空div标签')
                return '<p></p>'
              }
            )

            // 2.5 修复其他div标签，将普通div转换为p标签
            // 将 <div>内容</div> 转换为 <p>内容</p>
            processedHtml = processedHtml.replace(
              /<div>([^<]*)<\/div>/gi,
              (match, content) => {
                if (content.trim()) {
                  console.log('将普通div转换为p标签:', content.substring(0, 20) + (content.length > 20 ? '...' : ''))
                  return `<p>${content}</p>`
                }
                return match
              }
            )

            // 2.6 保留带样式的div，但转换为p标签
            // 将 <div style="...">内容</div> 转换为 <p style="...">内容</p>
            processedHtml = processedHtml.replace(
              /<div\s+style="([^"]*)">([\s\S]*?)<\/div>/gi,
              (_, style, content) => {
                console.log('将带样式的div转换为p标签:', style.substring(0, 20) + (style.length > 20 ? '...' : ''))
                return `<p style="${style}">${content}</p>`
              }
            )

            return processedHtml
          }

          // 处理HTML内容
          htmlContent = processHtmlContent(htmlContent)

          // 保存处理后的HTML内容
          article.contentHtml = htmlContent
          console.log('处理后HTML内容长度:', htmlContent.length)

        } else {
          error.value = result.msg || '获取文章失败'
        }
      } catch (err) {
        console.error('Error fetching article:', err)
        error.value = '获取文章失败，请稍后再试'

        // 如果文章ID不存在，跳转到创建新文章页面
        if (err.response && err.response.status === 404) {
          router.replace('/admin/articles/new')
        }
      } finally {
        loading.value = false
      }
    }

    // 保存文章
    const saveArticle = async () => {
      // 表单验证
      if (!article.title) {
        error.value = '请输入文章标题'
        return
      }

      if (!article.category) {
        error.value = '请选择文章分类'
        return
      }

      if (!article.contentHtml || article.contentHtml === '<p></p>') {
        error.value = '请输入文章内容'
        return
      }

      saving.value = true
      error.value = null

      try {
        // 准备要发送的数据，按照后端API要求的格式
        const articleData = {
          title: article.title,
          category: article.category,
          content_html: article.contentHtml,
          content_text: article.contentText,
          url: article.url,
          section: article.section
        }

        // 如果是创建模式且指定了文章ID，则添加到请求数据中
        if (!isEdit.value && article.newsId) {
          articleData.news_id = parseInt(article.newsId)
        }

        // 如果设置了发布时间，则添加到请求数据中
        if (article.pubTime) {
          try {
            // 将本地日期时间转换为ISO格式
            const pubDate = new Date(article.pubTime)
            articleData.pub_time = pubDate.toISOString()
          } catch (e) {
            console.error('发布时间格式化失败:', e)
            // 不设置发布时间，后端会使用当前时间
          }
        }

        let result

        if (isEdit.value) {
          // 更新文章
          result = await articleApi.updateArticle(articleId.value, articleData)

          if (result.code === 200) {
            // 更新成功，显示成功消息
            alert('文章更新成功')
          } else {
            error.value = result.msg || '更新文章失败'
          }
        } else {
          // 创建文章
          result = await articleApi.createArticle(articleData)

          if (result.code === 200 && result.data && result.data.news_id) {
            // 创建成功，跳转到编辑页面
            const newArticleId = result.data.news_id
            await router.push(`/admin/articles/edit/${newArticleId}`)
          } else {
            error.value = result.msg || '创建文章失败'
          }
        }
      } catch (err) {
        console.error('Error saving article:', err)
        error.value = '保存文章失败，请稍后再试'
      } finally {
        saving.value = false
      }
    }

    // 返回上一页
    const goBack = () => {
      router.push('/admin/articles')
    }

    // 获取当前用户可用的section选项
    const fetchSectionOptions = async () => {
      try {
        // 使用配置好的request实例，它会自动处理baseURL和token
        const response = await articleApi.getSectionOptions()

        if (response.code === 200 && response.data) {
          sectionOptions.value = response.data
        } else {
          console.error('获取section选项失败:', response.msg)
        }
      } catch (err) {
        console.error('获取section选项请求失败:', err)
      }
    }

    // 页面加载时初始化
    onMounted(async () => {
      console.log('组件挂载，开始初始化')

      // 获取section选项
      await fetchSectionOptions()

      // 检查是否为编辑模式
      const id = route.params.id
      if (id && id !== 'new') {
        console.log('编辑模式，文章ID:', id)
        isEdit.value = true
        articleId.value = id

        // 获取文章数据
        await fetchArticle(id)
        // console.log("文章数据回调，此时 article.contentHtml 应为处理后的值"+article.contentHtml)
      } else {
        console.log('新建模式')
      }
    })

    // 组件销毁时销毁编辑器
    onBeforeUnmount(() => {
      const editor = editorRef.value
      if (editor == null) return
      editor.destroy()
    })

    return {
      editorRef,
      article,
      isEdit,
      loading,
      saving,
      error,
      mode,
      toolbarConfig,
      editorConfig,
      formatDateTime,
      handleCreated,
      handleChange,
      saveArticle,
      goBack,
      sectionOptions
    }
  }
}
</script>

<style>
/* wangEditor样式已通过import导入 */
</style>
